/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package idp.settings;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author M Dekker
 */
public class SettingModel
{

    private Vector<SettingListener> _listeners = new Vector();
    private String _key;
    private String _value;

    private static Connection _connection;
    private static Vector<SettingModel> _settings = new Vector();

    /**
     * Constructor
     * 
     * @param key
     * @param value
     */
    private SettingModel(String key,String value)
    {
        _key = key;
        _value = value;
    }

    /**
     * 
     * @return The value
     */
    public String getValue()
    {
        return _value;
    }

    /**
     * Saves the value in the database
     * 
     * @param value
     */
    public void setValue(String value)
    {
        try
        {
            // Update the database
            Statement stat = Connect().createStatement();
            stat.executeUpdate("UPDATE settings SET value='" + value + "' WHERE key='" + _key + "'");
            stat.close();

            _value = value;

            // Notify all the listeners
            for (SettingListener l : _listeners)
            {
                l.SettingChanged(this);
            }
        }
        catch (SQLException ex)
        {
            Logger.getLogger(SettingModel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * 
     * @return The settings key
     */
    public String getKey()
    {
        return _key;
    }

    /**
     * Add a listener to this object, this object is notified on changes
     * 
     * @param l
     */
    public void AddListener(SettingListener l)
    {
        if (!_listeners.contains(l))
        {
            _listeners.add(l);
        }
    }

   /**
    * Removes a listener from this object
    * 
    * @param l
    */
    public void RemoveListener(SettingListener l)
    {
        _listeners.remove(l);
    }

    /**
     * Load a SettingModel by key
     * 
     * @param key The key
     * @return The setting model (if it exists)
     */
    public static SettingModel LoadByKey(String key)
    {
        Connect();
        
        // Check if the requested key exists
        for (SettingModel m : _settings)
        {
            if (m.getKey().equals(key))
            {
                return m;
            }
        }
        return null;
    }

    /**
     * Creates a new model, and checks if it doesn't allready exists
     * 
     * @param key The key
     * @return The SettingModel, if the key doesn't exist yet.
     */
    public static SettingModel CreateModel(String key)
    {
        // Check if the key doesn't exist
        if (LoadByKey(key) == null)
        {
            SettingModel model = new SettingModel(key,"");
            _settings.add(model);

            try
            {
                Statement stat = Connect().createStatement();
                stat.executeUpdate("INSERT INTO settings VALUES('" + key + "','')");
                stat.close();
            }
            catch (SQLException ex)
            {
                Logger.getLogger(SettingModel.class.getName()).log(Level.SEVERE, null, ex);
            }

            return model;
        }
        else
        {
            return null;
        }
    }

    /**
     * Creates a database connection, if it doesn't exists already
     *
     * @return The database connection
     */
    private static Connection Connect()
    {
        // Are we connected?
        if(_connection == null)
        {
            try
            {
                // Setup a new connection
                Class.forName("org.sqlite.JDBC");
                _connection = DriverManager.getConnection("jdbc:sqlite:settings.db");

                // Add the settings table
                Statement stat = _connection.createStatement();
                stat.executeUpdate("CREATE TABLE IF NOT EXISTS settings(key varchar(255),value varchar(255))");
                stat.close();

                // Load all entries from the table
                stat = _connection.createStatement();
                ResultSet result = stat.executeQuery("SELECT * FROM settings");
                while(result.next())
                {
                    try
                    {
                        _settings.add(new SettingModel(result.getString("key"),result.getString("value")));
                    }
                    catch (Exception ex)
                    {
                        Logger.getLogger(SettingModel.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                stat.close();
               
                return _connection;
            }
            catch (SQLException ex)
            {
                Logger.getLogger(SettingModel.class.getName()).log(Level.SEVERE, null, ex);
                _connection = null;
            }
            catch (ClassNotFoundException ex)
            {
                Logger.getLogger(SettingModel.class.getName()).log(Level.SEVERE, null, ex);
            }

            return null;
        }
        else
        {
            return _connection;
        }
    }
}
